/**
 * x组件 运行的底层数据操作
 */
export default {
  props: {
    // xone id，实际是用所属页面实例的索引，
    // xone id 需要该索引找到页面，因为受小程序数据不能有函数约束 元数据 和 数据 需要放到所属页面上
    xid: {
      type: String,
      default: ''
    },
    // 组件的元数据路径，用于在所属页面找到自己的原始的元数据
    xmetapath: {
      type: String,
      default: ''
    },
    // 组件的数据路径，指定组件操作的数据，属于所属页面的什么字段
    xdatapath: {
      type: String,
      default: ''
    }
  },
  computed: {
    /**
     * 组件的原始的元数据 
     */
    xmeta() {
      return this.getXPath(this.getHost().xmeta, this.xmetapath)
    },
  },
  created() {
    // xmeta 缓存区
    this.xmetaCache = {}
  },
  methods: {
    /**
     * 日志函数
     */
    debug(...args) {
      console.log('xone',...args)
    },

    /**
     * 基本 xpath 操作：读取
     */
    getXPath(data, path) {
      let xpath = path.split('.').filter(v=>v)
      for(let v of xpath) {
        if(!data) break
        data = data[v]
      }
      return data
    },
    /**
     * 基本 xpath 操作：写入
     */
    setXPath(data, path, value) {
      if(!data||!path) return
      let target = data
      let xpath = path.split('.').filter(v=>v)
      let key = xpath.splice(-1,1)[0]
      for(let apath of xpath) {
        if(!data) break
        target = target[apath]
      }
      this.$set(target, key, value)
    },

    /**
     * 获取所属页面实例
     */
    getHost() {
      if(this._host) return this._host
      let pages = getCurrentPages()
      let host = pages[this.xid]
      // #ifdef MP_WEIXIN || APP-PLUS
      host = host.$vm
      // #endif
      return this._host = host
    },
    /**
     * 获取 xone 根组件实例
     */
    getXOne() {
      if(this._xone) return this._xone
      return this._xone = this.getHost().getXOne()
    },

    /**
     * 获取数据
     * @param {*} xpath 数据 x 路径
     * @param {*} xbase 根路径
     * @param {*} defaultValue 默认值
     * @returns 
     */
    getXData(xpath='', {xbase=this.xdatapath, defaultValue}={}, debug) {
      if(debug) debugger
      let xdata = this.getHost().xdata
      if(xbase&&xpath&&xpath[0]!=='.') xpath = '.'+xpath
      xpath = xbase + xpath
      if(xpath) xdata = this.getXPath(xdata, xpath)
      return xdata===undefined?defaultValue:xdata
    },
    /**
     * 设置数据
     * @param {*} xpath 数据 x 路径
     * @param {*} value 新值
     * @param {*} xbase 根路径
     * @returns 
     */
    setXData(xpath='', value, xbase=this.xdatapath) {
      let xdata = this.getHost().xdata
      if(xbase&&xpath&&xpath[0]!=='.') xpath = '.'+xpath
      xpath = xbase + xpath
      if(typeof value==='function') {
        value(xdata, xpath, value)
      }else if(xpath) {
        this.setXPath(xdata, xpath, value)
      }
    },
    /**
     * 获取当前组件在数据列表组件中的索引 
     */
    getMyXDataIndex() {
      return (this.xdatapath||'').split('.').slice(-1)[0]
    },

    /**
     * 获取元数据
     * @param {*} xpath 元数据 x 路径
     * @param {*} options 根路径或者对象
     * @returns 
     */
    getXMeta(xpath, options={}, debug) {
      if(debug) debugger
      
      // 从xone xmeta 缓存获取
      let cahceKey
      if(options.isCache) {
        cahceKey = this.xmetapath+xpath
        let cache = this.getHost().xmetaCache[this.xmetapath+xpath]
        if(cache!==undefined) return cache 
      }

      // 路径与 base data 计算
      let xbase = options.xbase || this.xmeta
      let xmeta
      if(typeof xbase === 'string') {
        xmeta = this.getHost().xmeta 
      }else{
        xmeta = xbase
        xbase = ''
      }
      if(xbase&&xpath&&xpath[0]!=='.') xpath = '.'+xpath
      xpath = xbase + xpath

      // 获取 path 数据
      let ret
      if(xpath) ret = this.getXPath(xmeta, xpath)

      // xmeta 函数形式处理
      if((typeof ret==='function')&&!options.isRaw) ret = ret(this)
      // fetch 形式
      if(ret&&ret.xfetch&&!options.isRaw) {
        let option = ret
        let value = this.getXData(option.xfield, {xbase: option.xbase||'_xruntime'})
        if(value) {
          ret = value
        }else{
          if(!option.promise) {
            option.promise = option.xfetch&&option.xfetch(this).then(ret=>{
              option.promise = null
              this.setXData(option.xfield, ret, option.xbase||'_xruntime')
            })
          }
          ret = ret.defaultValue||[]
        }
      }
      // 从xone xmeta 缓存获取
      if(options.isCache) this.getHost().xmetaCache[cahceKey] = ret

      return ret===undefined?options.defaultValue:ret
    },
  }
}